package cn.melonlib.cores.graphql.comp;

import cn.hutool.core.util.ReflectUtil;
import cn.melonlib.cores.commons.model.entity.ApiEntity;
import cn.melonlib.cores.commons.model.entity.IEntity;
import cn.melonlib.cores.commons.model.entity.RecordEntity;
import cn.melonlib.cores.commons.model.entity.StringIdEntity;
import cn.melonlib.cores.jpa.model.bean.collections.JsonMap;
import cn.melonlib.cores.jpa.model.bean.impl.PaginationList;
import cn.melonlib.cores.model.anno.*;
import cn.melonlib.cores.model.input.OrderByInput;
import freemarker.template.Template;
import lombok.Data;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.aop.support.AopUtils;
import org.springframework.cglib.core.ReflectUtils;
import org.springframework.context.support.ApplicationObjectSupport;
import org.springframework.core.ResolvableType;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;

import javax.annotation.Resource;
import java.beans.PropertyDescriptor;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.*;
import java.util.stream.Collectors;

@Component
public class GraphQLSchemaTools extends ApplicationObjectSupport {

    @Resource
    private FreeMarkerConfigurer freemarkerConfig;

    private JsonMap<Object> transFields(PropertyDescriptor p, WorkerService service, Class<?> entType) {
        System.out.println(entType.getSimpleName() + ":" + p.getName());
        JsonMap<Object> json = JsonMap.createMap().append("label", AnnotationUtils.findAnnotation(ReflectUtil.getField(entType, p.getName()), ModelComment.class).value());
        Class<?> type = p.getPropertyType();
        if (IEntity.class.isAssignableFrom(type)) {
            json.append("name", p.getName() + "_id");
            json.append("data", type.getSimpleName().substring(0, 1).toLowerCase() + type.getSimpleName().substring(1) + "List");
        } else if (type.isEnum()) {
            json.append("name", p.getName());
            json.append("data", type.getSimpleName().substring(0, 1).toLowerCase() + type.getSimpleName().substring(1) + "Enums");
        } else if (Number.class.isAssignableFrom(type)) {
            json.append("name", p.getName());
            if (p.getName().endsWith("DateTime")) {
                json.append("data", "DateTime");
            } else if (p.getName().endsWith("Date")) {
                json.append("data", "Date");
            } else if (p.getName().endsWith("Time")) {
                json.append("data", "Time");
            } else {
                json.append("data", "Number");
            }
        } else if (Boolean.class.isAssignableFrom(type)) {
            json.append("name", p.getName());
            json.append("data", "Boolean");
        } else {
            json.append("name", p.getName());
            json.append("data", "input");
        }
        if (RecordEntity.class.isAssignableFrom(entType) && ReflectUtil.getField(entType, p.getName()).getDeclaringClass().equals(RecordEntity.class)) {
            json.append("record", true);
        } else {
            json.append("record", false);
        }
        return json;
    }

    public void createEntitySchema(String path) throws Exception {
        File root = new File(path);
        if (!root.exists()) {
            root.mkdirs();
        }
        System.out.println("开始生成...");
        Map<String, Object> beans = this.getApplicationContext().getBeansWithAnnotation(WorkerService.class);

        beans.entrySet().stream().filter(bean->AnnotationUtils.findAnnotation(AopUtils.getTargetClass(bean.getValue()), WorkerService.class).createSchema())
                .forEach(bean-> {
                    try {
                        createEntitySchema(path,AopUtils.getTargetClass(bean.getValue()));
                    } catch (Exception e) {
                        logger.error(e.getMessage(),e);
                    }
                });
    }

    public void createEntitySchema(String path, Class<?> serviceType) throws Exception {
        Service service = AnnotationUtils.findAnnotation(serviceType, Service.class);
        if (service == null) {
            return;
        }
        File root = new File(path);
        if (!root.exists()) {
            root.mkdirs();
        }
        Object bean = this.getApplicationContext().getBean(serviceType);
        String beanName = StringUtils.defaultIfBlank(AnnotationUtils.findAnnotation(serviceType, Service.class).value()
                , serviceType.getSimpleName().substring(0, 1).toLowerCase(Locale.ROOT) + serviceType.getSimpleName().substring(1));
        System.out.println(beanName);
        ClassPathResource classPathResource=new ClassPathResource("/templates/graphql_template.ftl");
        Template tpl = freemarkerConfig.getConfiguration().getTemplate("graphql_template.ftl", "utf-8");
        JsonMap<Object> params = JsonMap.createMap();
        WorkerService config = AnnotationUtils.findAnnotation(serviceType, WorkerService.class);
//        Entity entityTypeAnno = AnnotationUtils.findAnnotation(config.entity().entityType(), Entity.class);
//        String gqlType = StringUtils.defaultIfBlank(config.entity().name(), StringUtils.defaultIfBlank(entityTypeAnno == null ? "" : entityTypeAnno.name()
//                , config.entity().entityType().getSimpleName()));

        String entityType = StringUtils.isNotBlank(config.model().name()) ? config.model().name() : ResolvableType.forClass(serviceType).getSuperType().getGeneric(0).resolve().getSimpleName();
        String inputType = StringUtils.isNotBlank(config.model().name())?config.model().name():
                (config.model()!=null&&!Objects.equals(config.model().inputType(),IEntity.class) ? config.model().inputType().getSimpleName() : entityType);
        String filterType = StringUtils.isNotBlank(config.model().name())?config.model().name():
                (config.model()!=null&&!Objects.equals(config.model().filterType(),IEntity.class) ? config.model().filterType().getSimpleName() : entityType);
        params.append("entityType", entityType);
        params.append("inputType", inputType);
        System.out.println(Arrays.stream(serviceType.getMethods())
                .filter(m -> AnnotationUtils.findAnnotation(m, WorkerService.class) != null)
                .collect(Collectors.toList()));
        //CreateQuery
        List<String> ignores = Arrays.stream(config.ignores()).collect(Collectors.toList());
            /*
             TODO 生成查询接口
             */
        Arrays.stream(serviceType.getDeclaredMethods()).forEach(m->System.out.println(m));
        List<JsonMap<Object>> queryList = Arrays.stream(serviceType.getMethods())
                .filter(m -> AnnotationUtils.findAnnotation(m, WorkerQuery.class) != null)
                .filter(m -> !ignores.contains(m.getName())).map(GraphQlEq::new).distinct().map(GraphQlEq::getMethod)
                .map(m -> {
                    System.out.println(m);
                    WorkerQuery cfg = AnnotationUtils.findAnnotation(m, WorkerQuery.class);
                    JsonMap<Object> query = JsonMap.createMap().append("name", beanName + "_" + StringUtils.defaultIfBlank(cfg.name(), m.getName()));
                    Parameter[] parameters = m.getParameters();
                    List<JsonMap<String>> paramList = new ArrayList<>();
                    for (int i = 0; i < parameters.length; i++) {
                        JsonMap<String> prms = JsonMap.createMap();
                        prms.append("name", getParameterName(parameters[i]));
                        prms.append("comment",getParameterComment(parameters[i]));
                        if (Integer.class.isAssignableFrom(parameters[i].getType())) {
                            prms.append("type", "Int"+getParameterRequired(parameters[i]));
                        } else if (String.class.isAssignableFrom(parameters[i].getType())) {
                            prms.append("type", "String"+getParameterRequired(parameters[i]));
                        } else if (Boolean.class.isAssignableFrom(parameters[i].getType())||Boolean.TYPE.isAssignableFrom(parameters[i].getType())) {
                            prms.append("type", "Boolean"+getParameterRequired(parameters[i]));
                        } else if (Long.class.isAssignableFrom(parameters[i].getType())||Long.TYPE.isAssignableFrom(parameters[i].getType())) {
                            prms.append("type", "Float"+getParameterRequired(parameters[i]));
                        } else if (Double.class.isAssignableFrom(parameters[i].getType())||Double.TYPE.isAssignableFrom(parameters[i].getType())) {
                            prms.append("type", "Float"+getParameterRequired(parameters[i]));
                        } else if(List.class.isAssignableFrom(parameters[i].getType())){
                            Class<?> type=ResolvableType.forMethodParameter(m,i).getGeneric(0).toClass();
                            if(String.class.isAssignableFrom(type)){
                                prms.append("type","[String]"+getParameterRequired(parameters[i]));
                            }else{
                                prms.append("type", "["+filterType + "Filter]"+getParameterRequired(parameters[i]));
                            }
                        } else if(OrderByInput.class.isAssignableFrom(parameters[i].getType())){
                            prms.append("type","OrderBy"+getParameterRequired(parameters[i]));
                        } else {
                            prms.append("type", filterType + "Filter"+getParameterRequired(parameters[i]));
                        }
                        paramList.add(prms);
                    }
                    query.append("params", paramList);
                    Class r = m.getReturnType();
                    if (PaginationList.class.isAssignableFrom(r)) {
                        query.append("return", entityType + "EntityConnection");
                    } else if (Integer.class.isAssignableFrom(r)||Integer.TYPE.isAssignableFrom(r)) {
                        query.append("return",  entityType+"IntValue");
                    } else if (String.class.isAssignableFrom(r)) {
                        query.append("return", entityType+"StringValue");
                    } else if (Boolean.class.isAssignableFrom(r)||Boolean.TYPE.isAssignableFrom(r)) {
                        query.append("return", entityType+"BooleanValue");
                    } else if (Long.class.isAssignableFrom(r)||Long.TYPE.isAssignableFrom(r)) {
                        query.append("return", entityType+"LongValue");
                    } else if (Double.class.isAssignableFrom(r)||Double.TYPE.isAssignableFrom(r)) {
                        query.append("return", entityType+"DoubleValue");
                    } else if (List.class.isAssignableFrom(r)) {
                        Class<?> type=ResolvableType.forMethodReturnType(m).getGeneric(0).toClass();
                        if(String.class.isAssignableFrom(type)){
                            query.append("return","[String]");
                        }else{
                            query.append("return", entityType + "EntityConnection");
                        }
                    } else {
                        query.append("return", entityType + "EntityPackage");
                    }
                    WorkerComment comment = AnnotationUtils.findAnnotation(m, WorkerComment.class);
                    query.append("comment", comment == null ? "暂缺" : comment.value());
                    return query;
                }).collect(Collectors.toList());
        params.append("queryList", queryList);

            /*
             TODO 生成数据更新接口
             */
        List<JsonMap<Object>> mutationList = Arrays.stream(serviceType.getMethods())
                .filter(m -> AnnotationUtils.findAnnotation(m, WorkerStore.class) != null)
                .filter(m -> !ignores.contains(m.getName())).map(GraphQlEq::new).distinct().map(GraphQlEq::getMethod)
                .map(m -> {
                    WorkerStore cfg = AnnotationUtils.findAnnotation(m, WorkerStore.class);
                    JsonMap<Object> mutation = JsonMap.createMap().append("name", beanName + "_" + StringUtils.defaultIfBlank(cfg.name(), m.getName()));
                    Parameter[] parameters = m.getParameters();
                    List<JsonMap<String>> paramList = new ArrayList<>();
                    for (int i = 0; i < parameters.length; i++) {
                        JsonMap<String> prms = JsonMap.createMap();
                        prms.append("name", getParameterName(parameters[i]));
                        prms.append("comment",getParameterComment(parameters[i]));
                        if (Integer.class.isAssignableFrom(parameters[i].getType())||Integer.TYPE.isAssignableFrom(parameters[i].getType())) {
                            prms.append("type", "Int"+getParameterRequired(parameters[i]));
                        } else if (String.class.isAssignableFrom(parameters[i].getType())) {
                            prms.append("type", "String"+getParameterRequired(parameters[i]));
                        } else if (Boolean.class.isAssignableFrom(parameters[i].getType())||Boolean.TYPE.isAssignableFrom(parameters[i].getType())) {
                            prms.append("type", "Boolean"+getParameterRequired(parameters[i]));
                        }else if (Long.class.isAssignableFrom(parameters[i].getType())||Long.TYPE.isAssignableFrom(parameters[i].getType())) {
                            prms.append("type", "Float"+getParameterRequired(parameters[i]));
                        } else if (Double.class.isAssignableFrom(parameters[i].getType())||Double.TYPE.isAssignableFrom(parameters[i].getType())) {
                            prms.append("type", "Float"+getParameterRequired(parameters[i]));
                        } else if (List.class.isAssignableFrom(parameters[i].getType())) {
                            Class listType= ResolvableType.forMethodParameter(m,i).getGeneric(0).toClass();
                            if(String.class.isAssignableFrom(listType)){
                                prms.append("type", "[String]"+getParameterRequired(parameters[i]));
                            }else if (Boolean.TYPE.isAssignableFrom(listType)||Boolean.TYPE.isAssignableFrom(listType)){
                                prms.append("type", "[Boolean]"+getParameterRequired(parameters[i]));
                            }else if(IEntity.class.isAssignableFrom(listType)){
                                prms.append("type", "["+inputType + "Input"+"]"+getParameterRequired(parameters[i]));
                            }else if(Integer.TYPE.isAssignableFrom(listType)||Integer.TYPE.isAssignableFrom(listType)){
                                prms.append("type", "[Int]"+getParameterRequired(parameters[i]));
                            }else{
                                prms.append("type", "[Float]"+getParameterRequired(parameters[i]));
                            }
                        } else {
                            prms.append("type", inputType + "Input"+getParameterRequired(parameters[i]));
                        }
                        paramList.add(prms);
                    }
                    mutation.append("params", paramList);
                    Class r = m.getReturnType();
                    if (List.class.isAssignableFrom(r)) {
                        mutation.append("return", entityType + "EntityCollection");
                    } else if (Integer.class.isAssignableFrom(r)||Integer.TYPE.isAssignableFrom(r)) {
                        mutation.append("return", "Int");
                    } else if (String.class.isAssignableFrom(r)) {
                        mutation.append("return", "String");
                    } else if (Boolean.class.isAssignableFrom(r)||Boolean.TYPE.isAssignableFrom(r)) {
                        mutation.append("type", "Boolean");
                    } else if (Long.class.isAssignableFrom(r)||Long.TYPE.isAssignableFrom(r)) {
                        mutation.append("type", "Float");
                    } else if (Double.class.isAssignableFrom(r)||Double.TYPE.isAssignableFrom(r)) {
                        mutation.append("type", "Float");
                    } else {
                        mutation.append("return", entityType + "Entity");
                    }
                    WorkerComment comment = AnnotationUtils.findAnnotation(m, WorkerComment.class);
                    mutation.append("comment", comment == null ? "暂缺" : comment.value());
                    return mutation;
                })
                .collect(Collectors.toList());
        params.append("mutationList", mutationList);

            /*
            TODO 生成查询结果映射字段
             */
        Class<? extends IEntity> entityClass = config.model().modelType();
        Class<? extends IEntity> voClass = config.model().voType().equals(IEntity.class) ? entityClass : config.model().voType();
        List<JsonMap> fields = Arrays.stream(ReflectUtils.getBeanGetters(voClass)).filter(p -> !StringUtils.equals("id", p.getName())).map(p -> {
            Field field = null;
            ModelComment ec = null;
            Class superClass = voClass;
            while (!superClass.equals(StringIdEntity.class)) {
                try {
                    field = superClass.getDeclaredField(p.getName());
                    ec = AnnotationUtils.findAnnotation(field, ModelComment.class);
                    break;
                } catch (NoSuchFieldException e) {
                    superClass = superClass.getSuperclass();
                }
            }
            if (field == null) {
                logger.warn("属性没有找到对应映射的字段。");
            }
            return JsonMap.<Object>createMap().append("name", IEntity.class.isAssignableFrom(p.getPropertyType()) &&!ApiEntity.class.isAssignableFrom(p.getPropertyType())? p.getName() + "_id" : p.getName())
                    .append("type", entityTypeMaps(field,p.getPropertyType())).append("comment", ec == null ? "未说明" : ec.value());
        }).collect(Collectors.toList());
        params.append("fields", fields);

            /*
               TODO 生成提交表单映射字段
             */
        Class<? extends IEntity> inputClass = config.model().inputType().equals(IEntity.class) ? entityClass : config.model().inputType();
        List<JsonMap> inputs = Arrays.stream(ReflectUtils.getBeanGetters(inputClass)).filter(p -> !StringUtils.equals("id", p.getName())).map(p -> {
            Field field = null;
            ModelComment ec = null;
            Class superClass = inputClass;
            while (!superClass.equals(StringIdEntity.class)) {
                try {
                    field = superClass.getDeclaredField(p.getName());
                    ec = AnnotationUtils.findAnnotation(field, ModelComment.class);
                    break;
                } catch (NoSuchFieldException e) {
                    superClass = superClass.getSuperclass();
                }
            }
            if (field == null) {
                logger.warn("属性没有找到对应映射的字段。");

            }

            return JsonMap.<Object>createMap().append("name", IEntity.class.isAssignableFrom(p.getPropertyType())&&!ApiEntity.class.isAssignableFrom(p.getPropertyType()) ? p.getName() + "_id" : p.getName())
                    .append("type", entityTypeInputs(field,p.getPropertyType())).append("comment", ec == null ? "未说明" : ec.value());
        }).collect(Collectors.toList());
        params.append("inputs", inputs);
            /*
                TODO 生成过滤条件映射字段
             */
        Class<? extends IEntity> filterClass = config.model().filterType().equals(IEntity.class) ? entityClass : config.model().filterType();
        List<JsonMap> filters = Arrays.stream(ReflectUtils.getBeanGetters(filterClass)).filter(p -> !StringUtils.equals("id", p.getName())).map(p -> {
            Field field = null;
            ModelComment ec = null;
            Class superClass = filterClass;
            while (!superClass.equals(StringIdEntity.class)) {
                try {
                    field = superClass.getDeclaredField(p.getName());
                    ec = AnnotationUtils.findAnnotation(field, ModelComment.class);
                    break;
                } catch (NoSuchFieldException e) {
                    superClass = superClass.getSuperclass();
                }
            }
            if (field == null) {
                logger.warn("属性没有找到对应映射的字段。");
            }

            return JsonMap.<Object>createMap().append("name", IEntity.class.isAssignableFrom(p.getPropertyType()) ? p.getName() + "_id" : p.getName())
                    .append("type", entityFilterMaps(p.getPropertyType())).append("comment", ec == null ? "未说明" : ec.value());
        }).collect(Collectors.toList());
        params.append("filters", filters);
        List<JsonMap> extTypesVo=Arrays.stream(config.model().extendsTypes()).map(type->{
            List<JsonMap> extTypeFields=Arrays.stream(ReflectUtils.getBeanGetters(type)).map(p -> {
                Field field = null;
                ModelComment ec = null;
                Class superClass = type;
                while (!superClass.equals(Object.class)) {
                    try {
                        field = superClass.getDeclaredField(p.getName());
                        ec = AnnotationUtils.findAnnotation(field, ModelComment.class);
                        break;
                    } catch (NoSuchFieldException e) {
//                            e.printStackTrace();
                        superClass = superClass.getSuperclass();
                    }
                }

                if (field == null) {
                    logger.warn("属性没有找到对应映射的字段。");
                }
                return JsonMap.<Object>createMap().append("name", p.getName())
                        .append("type", entityTypeMaps(field,p.getPropertyType())).append("comment", ec == null ? "未说明" : ec.value());
            }).collect(Collectors.toList());
            ModelComment typeEc=AnnotationUtils.findAnnotation(type, ModelComment.class);
            return JsonMap.createMap().append("name",type.getSimpleName()).append("comment",typeEc==null?"未说明":typeEc.value())
                    .append("fields",extTypeFields);
        }).collect(Collectors.toList());
        List<JsonMap> extTypesIo=Arrays.stream(config.model().extendsTypes()).map(type->{
            List<JsonMap> extTypeFields=Arrays.stream(ReflectUtils.getBeanGetters(type)).map(p -> {
                Field field = null;
                ModelComment ec = null;
                Class superClass = type;
                while (!superClass.equals(Object.class)) {

                    try {
                        field = superClass.getDeclaredField(p.getName());
                        ec = AnnotationUtils.findAnnotation(field, ModelComment.class);
                        break;
                    } catch (NoSuchFieldException e) {
//                            e.printStackTrace();
                        superClass = superClass.getSuperclass();
                    }
                }
                if (field == null) {
                    logger.warn("属性没有找到对应映射的字段。");
                }
                return JsonMap.<Object>createMap().append("name", p.getName())
                        .append("type", entityTypeInputs(field,p.getPropertyType())).append("comment", ec == null ? "未说明" : ec.value());
            }).collect(Collectors.toList());
            ModelComment typeEc=AnnotationUtils.findAnnotation(type, ModelComment.class);
            return JsonMap.createMap().append("name",type.getSimpleName()).append("comment",typeEc==null?"未说明":typeEc.value())
                    .append("fields",extTypeFields);
        }).collect(Collectors.toList());

        params.append("support", Arrays.stream(config.model().support()).map(Enum::name).collect(Collectors.toList()));
        params.append("extTypesVo",extTypesVo);
        params.append("extTypesIo",extTypesIo);
        WorkerComment serviceComment = AnnotationUtils.findAnnotation(serviceType, WorkerComment.class);
        params.append("serviceComment", serviceComment == null ? "未说明" : serviceComment.value());
        ModelComment entityComment = AnnotationUtils.findAnnotation(entityClass, ModelComment.class);
        params.append("entityComment", entityComment == null ? "未说明" : entityComment.value());

        File file = new File(root, new StringBuilder("/").append(config.module()).append("/").append(beanName).append(".graphqls").toString());
        try {
            FileUtils.forceMkdirParent(file);
        } catch (Exception e) {
        }
        if (config.createSchema()) {
            try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "utf-8"))) {
                tpl.process(params, writer);
            } catch (Exception e) {
                logger.error(e.getMessage(), e);
            }
        }
    }

    private String entityTypeMaps(Field field,Class<?> type) {
        if (Integer.class.isAssignableFrom(type)||Integer.TYPE.isAssignableFrom(type)) {
            return "Int";
        } else if (String.class.isAssignableFrom(type)) {
            return "String";
        } else if (Long.class.isAssignableFrom(type)||Long.TYPE.isAssignableFrom(type)) {
            return "Float";
        } else if (Boolean.class.isAssignableFrom(type)||Boolean.TYPE.isAssignableFrom(type)) {
            return "Boolean";
        } else if (Double.class.isAssignableFrom(type)||Double.TYPE.isAssignableFrom(type)) {
            return "Float";
        } else if (Number.class.isAssignableFrom(type)) {
            return "Float";
        } else if (ApiEntity.class.isAssignableFrom(type)){
            return type.getSimpleName()+"Vo";
        }else if (List.class.isAssignableFrom(type)){
            Class<?> listType=ResolvableType.forField(field).getGeneric(0).toClass();
            if(ApiEntity.class.isAssignableFrom(listType)){
                return "["+listType.getSimpleName()+"Vo]";
            }else{
                return "[String]";
            }
        }else {
            return "String";
        }
    }

    private String entityTypeInputs(Field field,Class<?> type) {

        if (Integer.class.isAssignableFrom(type)||Integer.TYPE.isAssignableFrom(type)) {
            return "Int"+getFiledRequired(field);
        } else if (String.class.isAssignableFrom(type)) {
            return "String"+getFiledRequired(field);
        } else if (Long.class.isAssignableFrom(type)||Long.TYPE.isAssignableFrom(type)) {
            return "Float"+getFiledRequired(field);
        } else if (Boolean.class.isAssignableFrom(type)||Boolean.TYPE.isAssignableFrom(type)) {
            return "Boolean"+getFiledRequired(field);
        } else if (Double.class.isAssignableFrom(type)||Double.TYPE.isAssignableFrom(type)) {
            return "Float"+getFiledRequired(field);
        } else if (Number.class.isAssignableFrom(type)) {
            return "Float"+getFiledRequired(field);
        }else if (ApiEntity.class.isAssignableFrom(type)) {
            return type.getSimpleName()+"Io"+getFiledRequired(field);
        }else if (List.class.isAssignableFrom(type)){
            Class<?> listType=ResolvableType.forField(field).getGeneric(0).toClass();
            if(ApiEntity.class.isAssignableFrom(listType)){
                return "["+listType.getSimpleName()+"Io]"+getFiledRequired(field);
            }else{
                return "[String]"+getFiledRequired(field);
            }
        }else {
            return "String"+getFiledRequired(field);
        }
    }

    private String entityFilterMaps(Class<?> type) {
        if (Integer.class.isAssignableFrom(type)||Integer.TYPE.isAssignableFrom(type)) {
            return "intFilter";
        } else if (Long.class.isAssignableFrom(type)||Long.TYPE.isAssignableFrom(type)) {
            return "floatFilter";
        } else if (Double.class.isAssignableFrom(type)||Double.TYPE.isAssignableFrom(type)) {
            return "floatFilter";
        } else if(Boolean.class.isAssignableFrom(type)||Boolean.TYPE.isAssignableFrom(type)){
            return "booleanFilter";
        }else {
            return "stringFilter";
        }
    }

    public String getParameterName(Parameter parameter){
        WorkerParameter workerParameter=AnnotationUtils.findAnnotation(parameter, WorkerParameter.class);
        if(workerParameter!=null){
          return StringUtils.isBlank(workerParameter.value())?parameter.getName():workerParameter.value();
        }else{
            return parameter.getName();
        }
    }
    public String getParameterComment(Parameter parameter){
        WorkerParameter workerParameter=AnnotationUtils.findAnnotation(parameter, WorkerParameter.class);
        if(workerParameter!=null){
          return StringUtils.isBlank(workerParameter.comment())?"未说明":workerParameter.comment();
        }else{
            return "未说明";
        }
    }

    public String getParameterRequired(Parameter parameter){
        WorkerParameter workerParameter=AnnotationUtils.findAnnotation(parameter, WorkerParameter.class);
        if(workerParameter!=null){
          return workerParameter.required()?"!":"";
        }else{
            return "";
        }
    }

    public String getFiledRequired(Field f){
        ModelComment modelComment=AnnotationUtils.findAnnotation(f,ModelComment.class);
        if(modelComment==null){
            return "";
        }else{
            return modelComment.required()?"!":"";
        }
    }

}
@Data
class GraphQlEq{

    public GraphQlEq(Method method) {
        this.method = method;
    }

    private Method method;

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof GraphQlEq)) return false;
        GraphQlEq graphQlEq = (GraphQlEq) o;
        return Objects.equals(method.getName(), graphQlEq.method.getName());
    }

    @Override
    public int hashCode() {
        return Objects.hash(method.getName());
    }
}
